#include "ringqueue.h"


typedef struct
{
  uint16_t front;
  uint16_t rear;
  uint8_t* data;
  uint16_t Size;
  uint16_t Len;
}_FifoQueue;


#define S_BLE_UART_FIFO_SIZE (1000)
static uint8_t s_BleUartRx_Fifo_Buffer[S_BLE_UART_FIFO_SIZE];
static _FifoQueue s_BleUartRxFifoQueue={
		0,0,&s_BleUartRx_Fifo_Buffer[0],S_BLE_UART_FIFO_SIZE,0
};

#define S_UART_TX_FIFO_SIZE (1000)
static uint8_t s_BleUartTx_Fifo_Buffer[S_UART_TX_FIFO_SIZE];
static _FifoQueue s_BleUartTxFifoQueue={
		0,0,&s_BleUartTx_Fifo_Buffer[0],S_UART_TX_FIFO_SIZE,0
};




static void _RingQueueInit(_FifoQueue *q)
{
   q->front=q->rear=0;
}


static uint8_t _RingQueueIn(_FifoQueue *q,uint8_t data)
{
  
   if(((q->rear+1)%q->Size)==q->front)
   	return 1;
   q->data[q->rear]=data;
   q->rear=((q->rear+1)%q->Size);
   return 0;
}


static uint8_t _RingQueueOut(_FifoQueue *q,uint8_t* data)
{
   if(q->front==q->rear)
   	{
   	    return 1;
   	}
   (*data)=q->data[q->front];
   q->front=((q->front+1)%q->Size);
   return 0;
}



static uint8_t _RingQueueInBlock_Cycle(_FifoQueue *q,uint8_t* data,uint8_t length)
{
    uint16_t i=0;
	uint8_t flag;

   flag=0;
   for(i=0;i<length;i++)
   {
        q->data[q->rear]=data[i];
        q->rear=((q->rear+1)%q->Size);
        if(((q->rear+1)%q->Size)==q->front)
        {
           flag=1;
        }
   }
   if(flag>0)
       return 1;
   else
       return 0;

}


static uint8_t _RingQueueOutBlock_Cycle(_FifoQueue *q,uint8_t*buff,uint8_t buffMax,uint32_t* length)
{
     uint16_t i;
	 uint8_t datelen;
	 uint8_t flag;

     if(q->front==q->rear)
      {
             *length=0;
              return 0;
      }
      datelen=buffMax;
      flag=0;
      if(((q->rear-q->front+q->Size)%q->Size)<datelen)
      {
            datelen=(q->rear-q->front+q->Size)%q->Size;
      }
      else
      {
            flag=1;
      }
          
      for(i=0;i<datelen;i++)
       {
          if(q->front==q->rear)
          {
                 flag=2;
                 break;
          }
          *buff++=q->data[q->front];
          q->front=(q->front+1)%q->Size;
       }
     
       *length=i;
     
       if(1==flag)
       {
         return 1;
       }
     
       return 2;

	 
}


static uint16_t _RingQueueLength(_FifoQueue *q)
{
 
  return ((q->rear-q->front+q->Size)%q->Size);
}

static uint8_t _RingQueueOutBlock_Read(_FifoQueue *q,uint8_t*PBuff,uint8_t PLen,uint8_t*R_PLen)
{
   uint16_t i;
   uint16_t ReadLen;
   uint16_t RingBuffLen;
   uint16_t front_index;
   
    if(q->front==q->rear)
    {
         *R_PLen=0;
         return 0;
    }
    RingBuffLen=((q->rear-q->front+q->Size)%q->Size);
    if(PLen>RingBuffLen)
    {
        ReadLen=RingBuffLen;
    }
    else
    {
        ReadLen=PLen;
    }
    front_index=q->front;
    for(i=0;i<ReadLen;i++)
    {
       if(front_index==q->rear)
        {
           break;
        }
       PBuff[i]=q->data[front_index];
       front_index=(front_index+1)%q->Size;
    }
    *R_PLen=i;
    return 1;   
}



uint8_t UartRxBufferInit(void)
{
    _RingQueueInit(&s_BleUartRxFifoQueue);
	return 1;
}
/**
 * \brief   uart ????
 */ 

uint8_t UartRxBuffer_BlockIn(uint8_t* data,uint8_t length)
{
   return _RingQueueInBlock_Cycle(&s_BleUartRxFifoQueue,data,length);
}

/**
 * \brief  uart ????
 */ 

uint8_t UartRxBuffer_BlockOut(uint8_t*buff,uint8_t bufflen,uint32_t*length)
{
    return _RingQueueOutBlock_Cycle(&s_BleUartRxFifoQueue,buff,bufflen,length);
}

/**
 * \brief  Uart ??????
 */ 

uint16_t UartRxBuffer_Length(void)
{
    return _RingQueueLength(&s_BleUartRxFifoQueue);
}

/**
 * \brief  uart ?????????
 */ 

uint8_t UartRxBuffer_SIn(uint8_t data)
{
    return _RingQueueIn(&s_BleUartRxFifoQueue,data);
}
/**
 * \brief  uart ?????????
 */ 

uint8_t UartRxBuffer_SOut(uint8_t*data)
{
    return _RingQueueOut(&s_BleUartRxFifoQueue,data);
}
/**
 * \brief  uart ??????
 */ 

uint8_t UartRxBuffer_BlockRead(uint8_t*data,uint8_t dataLen,uint8_t* ReadLen)
{
     return _RingQueueOutBlock_Read(&s_BleUartRxFifoQueue,data,dataLen,ReadLen);
}






uint8_t UartTxBufferInit(void)
{
    _RingQueueInit(&s_BleUartTxFifoQueue);
	return 1;
}
/**
 * \brief   uart ????
 */ 

uint8_t UartTxBuffer_BlockIn(uint8_t* data,uint8_t length)
{
   return _RingQueueInBlock_Cycle(&s_BleUartTxFifoQueue,data,length);
}

/**
 * \brief  uart ????
 */ 

uint8_t UartTxBuffer_BlockOut(uint8_t*buff,uint8_t bufflen,uint32_t*length)
{
    return _RingQueueOutBlock_Cycle(&s_BleUartTxFifoQueue,buff,bufflen,length);
}

/**
 * \brief  Uart ??????
 */ 

uint16_t UartTxBuffer_Length(void)
{
    return _RingQueueLength(&s_BleUartTxFifoQueue);
}

/**
 * \brief  uart ?????????
 */ 

uint8_t UartTxBuffer_SIn(uint8_t data)
{
    return _RingQueueIn(&s_BleUartTxFifoQueue,data);
}
/**
 * \brief  uart ?????????
 */ 

uint8_t UartTxBuffer_SOut(uint8_t*data)
{
    return _RingQueueOut(&s_BleUartTxFifoQueue,data);
}
/**
 * \brief  uart ??????
 */ 

uint8_t UartTxBuffer_BlockRead(uint8_t*data,uint8_t dataLen,uint8_t* ReadLen)
{
     return _RingQueueOutBlock_Read(&s_BleUartTxFifoQueue,data,dataLen,ReadLen);
}






